package com.kgcx.push.utils;

import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Properties;

/**
 * @author 何凯
 * @version 0.1
 * @description
 * @time 2018/1/11 17:30
 * @since 0.1
 */
public class FtpsUtils {

    private static Logger logger = LoggerFactory.getLogger(FtpsUtils.class);
    private static FtpsUtils ftpsUtils;
    private FTPSClient ftpsClient;

    private String serverUrl; //服务器地址
    private String port; // 服务器端口
    private String username; // 用户登录名
    private String password; // 用户登录密码
    private String url;//远程图片地址
    private InputStream is; // 文件下载输入流

    public static void main(String[] args){
        new FtpsUtils().initConfig();
    }

    /**
     * 私有构造方法
     */
    private FtpsUtils() {
        initConfig();
        if (null == ftpsClient) {
            ftpsClient = new FTPSClient();
        }
    }
    /**
     * 获取ftpsUtils对象实例
     *
     * @return ftpsUtils对象实例
     */
    public synchronized static FtpsUtils getInstance() {
        if (null == ftpsUtils) {
            ftpsUtils = new FtpsUtils();
        }
        return ftpsUtils;
    }

    /**
     * 初始化FTP服务器连接属性
     */
    public void initConfig() {
        // 构造Properties对象
        Properties properties = new Properties();
        try {
            InputStream is = FtpsUtils.class.getClassLoader().getResourceAsStream("ftpConfig.properties");
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 172.30.50.104ftp读取配置文件
        serverUrl = (String) properties.get("host"); // 设置服务器地址
        port = (String) properties.get("port"); // 设置端口
        password = (String) properties.get("password"); // 设置密码
        username = (String) properties.get("userName"); // 设置用户名
    }

    /**
     * 连接（配置通用连接属性）至服务器
     *
     * @param remotePath
     *            服务器名称
     * @param remotePath
     *            当前访问目录
     * @return <b>true</b>：连接成功 <br/>
     *         <b>false</b>：连接失败
     */
    public boolean connectToTheServer(String remotePath) {
        // 定义返回值
        boolean result = false;
        try {
            // 连接至服务器，端口默认为21时，可直接通过URL连接
            ftpsClient.connect(serverUrl, Integer.parseInt(port));
            // 登录服务器
            ftpsClient.login(username, password);
            // 判断返回码是否合法
            if (!FTPReply.isPositiveCompletion(ftpsClient.getReplyCode())) {
                // 不合法时断开连接
                ftpsClient.disconnect();
                // 结束程序
                return result;
            }
            //设置文件传输模式
            //被动模式
//          ftpsClient.enterLocalPassiveMode();
            //创建目录
            ftpsClient.makeDirectory(remotePath);
            // 设置文件操作目录
            result = ftpsClient.changeWorkingDirectory(remotePath);
            // 设置文件类型，二进制
            result = ftpsClient.setFileType(ftpsClient.BINARY_FILE_TYPE);
            // 设置缓冲区大小
            ftpsClient.setBufferSize(3072);
            // 设置字符编码
            ftpsClient.setControlEncoding("UTF-8");

        } catch (IOException e) {
            logger.error("连接FTP服务器异常",e);
            throw new RuntimeException("连接FTP服务器异常" , e);
        }
        return result;
    }

    /**
     * 上传文件至FTP服务器
     *
     * @param storePath
     *            服务器名称
     * @param storePath
     *            上传文件存储路径
     * @param fileName
     *            上传文件存储名称
     * @param is
     *            上传文件输入流
     * @return <b>true</b>：上传成功 <br/>
     *         <b>false</b>：上传失败
     */
    public boolean storeFile( String storePath, String fileName, InputStream is) {
        boolean result = false;
        try {
            // 连接至服务器
            result = connectToTheServer(storePath);
            // 判断服务器是否连接成功
            if (result) {
                // 上传文件
                result = ftpsClient.storeFile(fileName, is);
            }
            // 关闭输入流
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 判断输入流是否存在
            if (null != is) {
                try {
                    // 关闭输入流
                    is.close();
                } catch (IOException e) {
                    logger.error("上传文件至FTP异常"+e.getMessage());
                    throw new RuntimeException("上传文件至FTP异常" , e);
                }
            }
            // 登出服务器并断开连接
            ftpsUtils.logout();
        }
        return result;
    }



    /**
     * 登出服务器并断开连接
     *            ftpsClient对象实例
     * @return <b>true</b>：操作成功 <br/>
     *         <b>false</b>：操作失败
     */
    public boolean logout() {
        boolean result = false;
        if (null != is) {
            try {
                // 关闭输入流
                is.close();
            } catch (IOException e) {
                logger.error("登录FTP服务器异常"+e.getMessage());
                throw new RuntimeException("登录FTP服务器异常" , e);
            }
        }
        if (null != ftpsClient) {
            try {
                // 登出服务器
                result = ftpsClient.logout();
            } catch (IOException e) {
                logger.error("登录FTP服务器异常"+e.getMessage());
                throw new RuntimeException("登录FTP服务器异常" , e);
            } finally {
                // 判断连接是否存在
                if (ftpsClient.isConnected()) {
                    try {
                        // 断开连接
                        ftpsClient.disconnect();
                    } catch (IOException e) {
                        logger.error("关闭FTP服务器异常"+e.getMessage());
                        throw new RuntimeException("关闭FTP服务器异常" , e);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 把配置文件先写到本地的一个文件中取
     *
     * @param fileName
     * @param fileContext
     * @return
     */
    public boolean write(String fileName, String fileContext,
                         String writeTempFielPath) {
        try {
            logger.info("开始写配置文件");
            File f = new File(writeTempFielPath + "/" + fileName);
            if(!f.exists()){
                if(!f.createNewFile()){
                    logger.info("文件不存在，创建失败!");
                }
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
            bw.write(fileContext.replaceAll("\n", "\r\n"));
            bw.flush();
            bw.close();
            return true;
        } catch (Exception e) {
            logger.error("写文件没有成功");
            e.printStackTrace();
            return false;
        }
    }


}
